package cn.sh.library.gmwx.controller;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.sh.library.gmwx.rateLimit.RateLimiterUtils;
import cn.sh.library.gmwx.service.RedisService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.view.RedirectView;

import cn.sh.library.gmwx.bean.InstanceSearchBean;
import cn.sh.library.gmwx.dto.Pager;
import cn.sh.library.gmwx.service.BookService;
import cn.sh.library.gmwx.service.RemoteService;
import cn.sh.library.gmwx.sparql.InstanceSparql;
import cn.sh.library.gmwx.sparql.ItemSparql;
import cn.sh.library.gmwx.sparql.WorkSparql;
import cn.sh.library.gmwx.utils.FullLink;
import cn.sh.library.gmwx.utils.JSONUtils;
import cn.sh.library.gmwx.utils.RDFUtils;
import cn.sh.library.gmwx.utils.StringUtilC;
import cn.sh.library.gmwx.utils.IPUtils;
import net.sf.json.JSONArray;

@Controller
@RequestMapping("/instance")
public class InstanceController extends BaseController {
    @Resource
    private BookService bookService;
//    @Resource
//    private WorkSparql workSparql;
    @Resource
    private InstanceSparql instanceSparql;
    @Resource
    private ItemSparql itemSparql;
//    @Resource
//    private RemoteService remoteService;

    @Resource
    private RateLimiterUtils rateLimiterUtils;

    // 预加载
    @Resource(name="preloadPersonInfo")
    private Map<String, String> preloadPersonInfo; // PreLoadPersonName类

    @Resource
    private RedisService redisService;

    // 书目：全文检索 + 高级检索
    @ResponseBody
    @RequestMapping(value = "/search", method = RequestMethod.GET)
    public String search(InstanceSearchBean search, Pager pager) throws IllegalArgumentException, IllegalAccessException{
        Map<String, Object> result = new HashMap<>();
        search = (InstanceSearchBean)StringUtilC.convertModel(search);
		List<Map<String, String>> list = this.bookService.instances(search, pager);
		// 查询并放入personInfoList信息, 并将List<Map<String, String>>转为List<Map<String, Object>>
		List<Map<String, Object>> newList = listMapStringString_to_listMapStringObject(list);
		result.put("resultList", newList);
		result.put("pager", pager);
		return JSONUtils.toJSon(result);
    }

    // 获取书目RDF
    @ResponseBody
    @RequestMapping(value = "/rdf", method = RequestMethod.GET)
    public void rdf(HttpServletResponse response, String uri){
        ByteArrayOutputStream bos = (ByteArrayOutputStream) instanceSparql.instanceTempModel(uri);
        byte[] data = bos.toByteArray();
        String rdfData = new String(data, Charset.forName("utf-8"));
        response.setContentType("application/rdf+xml");
        try {
            response.getWriter().write(rdfData);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    // 手动执行-预加载
    @ResponseBody
    @RequestMapping(value = "/updateFacet", method = RequestMethod.GET)
    public String updateFacet() {
        this.instanceSparql.updateFacetInstance("bf:provisionActivity/bf:date", "time:Instant");
        this.instanceSparql.updateFacetInstance("bf:provisionActivity/bf:place", "shl:Place");
        this.instanceSparql.updateFacetInstance("bf:provisionActivity/bf:agent", "shl:Organization");
        this.instanceSparql.countInstance();

        return "SUCCESS";
    }

    // 年份-分面
    @ResponseBody
    @RequestMapping(value = "/facetYear", method = RequestMethod.GET)
    public String facetYear(InstanceSearchBean search) {
        Map<String, Object> result = new HashMap<>();
        result.put("type", this.instanceSparql.countInstanceFacet(search, "bf:provisionActivity/bf:date"));
        return JSONUtils.toJSon(result);
    }

    // 出版地-分面
    @ResponseBody
    @RequestMapping(value = "/facetPlace", method = RequestMethod.GET)
    public String facetPlace(InstanceSearchBean search) {
        Map<String, Object> result = new HashMap<>();
        result.put("type", this.instanceSparql.countInstanceFacet(search, "bf:provisionActivity/bf:place"));
        return JSONUtils.toJSon(result);
    }

    // 出版社-分面
    @ResponseBody
    @RequestMapping(value = "/facetPublisher", method = RequestMethod.GET)
    public String facetPublisher(InstanceSearchBean search) {
        Map<String, Object> result = new HashMap<>();
        result.put("type", this.instanceSparql.countInstanceFacet(search, "bf:provisionActivity/bf:agent"));
        return JSONUtils.toJSon(result);
    }
    
    // 是否全文-分面
    @ResponseBody
    @RequestMapping(value = "/facetFullTextFlg", method = RequestMethod.GET)
    public String facetFullTextFlg(InstanceSearchBean search) {
        Map<String, Object> result = new HashMap<>();
        result.put("type", this.instanceSparql.countInstanceFacet(search, "shl:image"));
        return JSONUtils.toJSon(result);
    }

    // 书目详情
    @ResponseBody
    @RequestMapping(value = "/detail", method = RequestMethod.GET)
    public String detail(HttpServletRequest request, String uri,Integer reload){
        String limitRes = rateLimiterUtils.limit(request, "_detail", 60, 60, true);
        if(limitRes != null && limitRes.length() > 0){
            Map<String, Object> result = new HashMap<>();
            result.put("msg", limitRes);
            return JSONUtils.toJSon(result);
        }
        return getDetailString(request, uri, reload);
    }

    @ResponseBody
    @RequestMapping(value = "/detailNoLimit", method = RequestMethod.GET)
    public String detailNoLimit(HttpServletRequest request, String uri,Integer reload){
        return getDetailString(request, uri, reload);
    }

    private String getDetailString(HttpServletRequest request, String uri, Integer reload) {
        if((reload == null || reload != 1) && redisService.hasKeyByUri(uri, "detail")){
            return redisService.getByUri(uri, "detail").toString();
        }else{
            String detailString = getDetailString(request, uri);
            redisService.saveByUri(uri, "detail", detailString);
            return detailString;
        }
    }

    @ResponseBody
    @RequestMapping(value = "/detailInfo", method = RequestMethod.GET)
    public String detailInfo(HttpServletRequest request, String uri){
        return getDetailString(request, uri);
    }
    private String getDetailString(HttpServletRequest request, String uri) {
        Map<String, Object> result = new HashMap<>();
        result.put("uri", uri);
        result.put("infos", this.instanceSparql.getBibInfos(uri));
        result.put("contributions", RDFUtils.transformListMap2(this.instanceSparql.getContributions(uri)));
        result.put("works", this.instanceSparql.getWorks(uri));
        result.put("items", this.itemSparql.getInstanceItems(uri));
        //内外网IP标志: true：内网, false:外网
        result.put("ipFlg", String.valueOf(IPUtils.isPrivateIP()));
        System.out.println("判断为:"+String.valueOf(IPUtils.isPrivateIP()));
        System.out.println("IP为:"+FullLink.getIpAddr(request));
        return JSONUtils.toJSon(result);
    }

    // 年份 + 出版地 + 出版社 + 是否全文 - 分面
    @ResponseBody
    @RequestMapping(value = "/facetAll", method = RequestMethod.GET)
    public String count(InstanceSearchBean search){
        Map<String, Object> result = new HashMap<>();
        result.put("year", this.instanceSparql.countInstanceFacet(search, "bf:provisionActivity/bf:date"));
        result.put("place", this.instanceSparql.countInstanceFacet(search, "bf:provisionActivity/bf:place"));
        result.put("publisher", this.instanceSparql.countInstanceFacet(search, "bf:provisionActivity/bf:agent"));
        result.put("fullTextFlgList", this.instanceSparql.countInstanceFacet(search, "shl:image"));
        return JSONUtils.toJSon(result);
    }

    @ResponseBody
    @RequestMapping(value = "/placeInArea", method = RequestMethod.GET)
    public String placeInArea(InstanceSearchBean search, String points){
        Map<String, Object> result = new HashMap<>();
        result.put("data", this.instanceSparql.getPlacesInArea(points, search));
        return JSONUtils.toJSon(result);
    }

    @ResponseBody
    @RequestMapping(value = "/placeInAreaCount", method = RequestMethod.GET)
    public String placeInAreaCount(InstanceSearchBean search, String points){
        Map<String, Object> result = new HashMap<>();
        result.put("data", this.instanceSparql.getPlacesInAreaCount(points, search));
        return JSONUtils.toJSon(result);
    }
    
    // 查询并放入personInfoList信息, 将List<Map<String, String>>转为List<Map<String, Object>>, "personInfoList"(String键) : List类型值(非String值)
    @SuppressWarnings({ "rawtypes", "unchecked" })
	private List<Map<String, Object>> listMapStringString_to_listMapStringObject(List<Map<String, String>> list) {
    	List<Map<String, Object>> newList = new ArrayList<Map<String, Object>>();
		for (Map info : list) {
			 List<Map<String, String>> personInfoList = new ArrayList<Map<String, String>>();
             if(!StringUtilC.isEmpty(info.get("personInfos"))) {
            	// 查询并放入personInfoList信息
             	String [] personMessageList = info.get("personInfos").toString().split(";");
             	for (String personMessage : personMessageList) {
             		String [] personUriAndPersonRole = personMessage.split("~");
             		if(personUriAndPersonRole.length>0) {
             			String personUri = StringUtilC.getString(personUriAndPersonRole[0]);
             			String personRole = StringUtilC.getString(personUriAndPersonRole.length>1?personUriAndPersonRole[1]:"");
             			String personName = StringUtilC.getString(preloadPersonInfo.get(personUri));
             			Map<String, String> personInfo = new HashMap<String, String>();
             			personInfo.put("personUri", personUri);
             			personInfo.put("personRole", personRole);
             			personInfo.put("personName", personName);
             			personInfoList.add(personInfo);
             		}
             	}
             }
             info.put("personInfoList", JSONArray.fromObject(personInfoList));
             newList.add((Map)(info));
		}
    	return newList;
    }
    //add by CM 20190219
    

//    @ResponseBody
    @RequestMapping(value = "/cover", method = RequestMethod.GET)
    public Object cover(String uri) {
        Map<String, Object> result = new HashMap<>();
//        search = (InstanceSearchBean)StringUtilC.convertModel(search);
//		List<Map<String, String>> list = this.bookService.instances(search, pager);
//		// 查询并放入personInfoList信息, 并将List<Map<String, String>>转为List<Map<String, Object>>
//		List<Map<String, Object>> newList = listMapStringString_to_listMapStringObject(list);
//		result.put("resultList", newList);
//		result.put("pager", pager);
        String image = bookService.coverByInstance(uri);
        if(StringUtils.isEmpty(image)) {
        	image = "https://red.library.sh.cn/default.png";
        }
        
		return new RedirectView(image);
    }
    
}
